#wxNAPEntry
#Derived from wxSurvivalEntry
#
#Implements NAP style input into the wxgrid. 

use Wx 0.15 qw[:allclasses];
use strict;

package wxNAPEntry;
use base qw(wxSurvivalEntry);
use Wx qw[:everything];

#Constructor
sub new {
    my $self = shift;
    #call the constructor of the parent class, Person.
    $self = $self->SUPER::new( @_ );

	#button for setting variable constant 
	$self->{button_make_constant} = Wx::Button->new($self->{panel_grid}, -1, "Make Variable");
	$self->{sizer}->Add($self->{button_make_constant}, 0,  wxCENTER);

	Wx::Event::EVT_GRID_SELECT_CELL($self, \&set_button);
	Wx::Event::EVT_GRID_CELL_CHANGE($self, \&set_survival);
	Wx::Event::EVT_BUTTON($self, $self->{button_make_constant}->GetId, \&toggle_constant);
	Wx::Event::EVT_SPLITTER_SASH_POS_CHANGED($self, $self->GetId, \&set_splitter_position); 
	Wx::Event::EVT_SPLITTER_SASH_POS_CHANGING($self, $self->GetId, \&set_splitter_position); 
	

    return $self;
}


#Sets the sash position to the minimum value, or if triggered
#by a sash position change it enforces the minimum value
sub set_splitter_position {
	my ($self, $event) = @_;
	
	my $proposed;
	if (defined $event) {
		$proposed = $event->GetSashPosition();
	} else {
		$proposed = $self->GetSashPosition();
	}
	
	my $minimum = $self->{grid}->GetRowLabelSize();
	for (my $index = 0; $index < $self->{grid}->GetNumberCols(); $index++) {
		$minimum += $self->{grid}->GetColSize($index);
	}

	#On an event we only want to enforce that the button stays
	if (defined $event) {
		$minimum = $self->{sizer}->GetMinSize()->GetWidth();
	}

	my $width = $self->GetSize()->GetWidth();
	my $maximum = $width - 50;
	
	if ($proposed > $maximum) {
		$proposed = $maximum;
	}
	if ($proposed < $minimum) {
		$proposed = $minimum;
	}
	if ($proposed > $width) {
		$proposed = $width-10;
	}
	if (defined $event) {
		$event->SetSashPosition($proposed);
		$event->Skip();
	} else {
		$self->SetSashPosition($proposed);
	}
}

#Toggle whether a column is constant or not
sub toggle_constant {
	my ($self, $event) = @_;
	my $col = $self->{grid}->GetGridCursorCol();

	if (defined $col) {
		my $label = $self->{grid}->GetColLabelValue($col);
		if ($self->{constant}->{$label}) {
			$self->{constant}->{$label} = 0;
		} else {
			$self->{constant}->{$label} = 1;
		}
		$self->set_constant_col($col);	
	}
	
	$self->set_button();
	$self->set_survival();
	if (defined $event) { $event->Skip(); }
}

#Set a column's appearance according to its constant state 
sub set_constant_col {
	my ($self, $col) = @_;
	my $label = $self->{grid}->GetColLabelValue($col);
	
	my $backColour;
	
	for (my $row = 1; $row < $self->{grid}->GetNumberRows(); $row++) {
		$self->enable_cell($row,$col,!$self->{constant}->{$label});
	}
	$self->{grid}->Refresh();	
}

#Set the toggle button label as cells are clicked
sub set_button {
	my ($self, $event) = @_;
	
	my $col;
	if (defined $event) {
		$col = $event->GetCol();
	} else {
	$col = $self->{grid}->GetGridCursorCol();;
	}
	
	if (!defined $col || $self->{grid}->GetColLabelValue($col) eq 'Plot') {
		$self->{button_make_constant}->SetLabel('Make Constant');
		$self->{button_make_constant}->Disable();
	} elsif ( $self->{constant}->{$self->{grid}->GetColLabelValue($col)} ) {
		$self->{button_make_constant}->SetLabel('Make Variable');
		$self->{button_make_constant}->Enable();
	} else {
		$self->{button_make_constant}->SetLabel('Make Constant');
		$self->{button_make_constant}->Enable();
	}
	if (defined $event) { $event->Skip(); }
}

#Add the NAP specific columns
sub blank_grid {
	my $self = shift;
	$self->SUPER::blank_grid();
	
	$self->insert_col("Conservation\nCost");
	$self->insert_col("Conserved\nProbability");
	$self->insert_col("Unconserved\nProbability");
	$self->{constant}->{"Conservation\nCost"} = 1;
	$self->{constant}->{"Conserved\nProbability"} = 1;
	$self->{constant}->{"Unconserved\nProbability"} = 1;
	$self->set_constant_col(0);
	$self->set_constant_col(1);
	$self->set_constant_col(2);
	$self->{grid}->Fit();
	
}

#Fill the grid with values from the survival probability object
sub fill_grid {
	my $self = shift;
	
	my %survival = $self->{state}->{survival_nap}->get_linear_survival();
	
	my %constant_check;
	
	my @var = ('a','b','c');
	my $cols = {'a'=>0,'b'=>1,'c'=>2};
	
	#For each row (species)
	for (my $index = 0; $index < $self->{grid}->GetNumberRows(); $index++) {
		#Get species name
		my $species = $self->{grid}->GetRowLabelValue($index);
		#For each variable (a,b,c)
		foreach (@var) {
			#This should never happen!
			unless (defined  $survival{$species}) {
				$survival{$species}->{$_}='';
			}
			#Set the cell value
			$self->{grid}->SetCellValue($index, $cols->{$_}, $survival{$species}->{$_});
			#Use a hash to check whether there is more than one unique value per column
			$constant_check{$_}->{$survival{$species}->{$_}} = 1;
		}
	}
	
	#Make any variable rows variable
	foreach (@var) {
		#If there is more than one unique value set the column variable
		if (scalar keys %{$constant_check{$_}} > 1) {
			$self->{constant}->{$self->{grid}->GetColLabelValue($cols->{$_})} = 0;
			$self->set_constant_col($cols->{$_});
		}
	}
	#Set the toggle button appropriately
	$self->set_button();
}

#Set the survival object from the grid: a bit messy but works
sub set_survival {
	my $self = shift;
	my $a_label = $self->{grid}->GetColLabelValue(0);
	my $b_label = $self->{grid}->GetColLabelValue(1);
	my $c_label = $self->{grid}->GetColLabelValue(2);
	
	my $survival = $self->{state}->{survival_nap};

	#Blank the survival probabilities
	$survival->set_survivalprobabilities_blank();
	
	my $constant_a = $self->{constant}->{$a_label} && $self->{constant}->{$c_label};
	my $constant_b = $self->{constant}->{$b_label} && $self->{constant}->{$c_label};
	
	#Add constant no conservation point
	if ($constant_a) {
		$survival->add_point($survival->get_names(), 0, $self->{grid}->GetCellValue(0,0));
	}
	#Add constant conservation point
	if ($constant_b) {
		$survival->add_point($survival->get_names(), $self->{grid}->GetCellValue(0,2), $self->{grid}->GetCellValue(0,1));
	}
	
	#If either point varies on a per species basis
	unless ($constant_a && $constant_b) {
		#We add a point per species
		for (my $row = 0; $row < $self->{grid}->GetNumberRows(); $row++) {
			my $cost;
			#Get the cost
			if ($self->{constant}->{$c_label}) { $cost = $self->{grid}->GetCellValue(0,2); }
			else { $cost = $self->{grid}->GetCellValue($row,2); }
			
			#Get the species name
			my $species_name = $self->{grid}->GetRowLabelValue($row);
			
			#If adding a per species no conservation point
			unless ($constant_a) {
				if ($self->{constant}->{$a_label}) { $a = $self->{grid}->GetCellValue(0,0); }
				else { $a = $self->{grid}->GetCellValue($row,0) }
				$survival->add_point($species_name, 0, $a);
			}
			
			#If adding a per species conservation point
			unless ($constant_b) {
				if ($self->{constant}->{$b_label}) { $b = $self->{grid}->GetCellValue(0,1); }
				else { $b = $self->{grid}->GetCellValue($row,1) }
				$survival->add_point($species_name, $cost, $b);
			}
		}				
	}
	$self->plot_survival();	
}

#Check whether a cell is a boolean value (last column)
sub is_bool {
	my ($self, $row, $col) = @_;
	
	unless (defined $row && defined $col) { return 0; }
	if ($col == $self->{grid}->GetNumberCols()-1) { return 1;}
	
	return 0;
}

1;